/*
 * File:   accueil.cpp
 * Author: E084412C
 *
 * Created on 29 janvier 2013, 14:03
 */
#include <sstream>
#include "accueil.h"
#include "modele/User.h"
#include "vue/addListDialog.h"
#include "vue/addTaskWindow.h"
#include "vue/editTaskWindow.h"
#include "vue/addTempDialog.h"
#include "vue/editListDialog.h"


#include "QMessageBox"
 
    User utilisateur;

accueil::accueil() {
    widget.setupUi(this);
    
    restoreDom();
    
    updateViewTasksList();
    
    ListOfTask *template1 = new ListOfTask("template1");
    Task *tache1 = new Task("tacheTemplate", false);
    template1->addTask(tache1);
    utilisateur.addTemplate(template1);
    
    
    widget.removeListBtn->setDisabled(true);
    widget.modifyListBtn->setDisabled(true);
    
    widget.removeTaskBtn->setDisabled(true);
    widget.modifyTaskBtn->setDisabled(true);
    
    
    QObject::connect(widget.addListBtn, SIGNAL(clicked()), this, SLOT(addListListener()));
    QObject::connect(widget.removeListBtn, SIGNAL(clicked()), this, SLOT(removeList()));
    QObject::connect(widget.modifyListBtn, SIGNAL(clicked()), this, SLOT(editListListener()));
    
    QObject::connect(widget.tableLists, SIGNAL(itemSelectionChanged()), this, SLOT(updateViewTasksList()));
    
    QObject::connect(widget.tableLists, SIGNAL(itemSelectionChanged()), this, SLOT(disableBtnTask()));
    
    QObject::connect(widget.treeTasks, SIGNAL(itemSelectionChanged()), this, SLOT(enableBtnTask()));
    
    QObject::connect(widget.addTaskBtn, SIGNAL(clicked()), this, SLOT(addTaskListener()));
    
    QObject::connect(widget.removeTaskBtn, SIGNAL(clicked()), this, SLOT(supprTaskListener()));
    
    QObject::connect(widget.modifyTaskBtn, SIGNAL(clicked()), this, SLOT(editTaskListener()));
    
    QObject::connect(widget.treeTasks, SIGNAL(itemDoubleClicked(QTreeWidgetItem* ,int)), this, SLOT(editTaskListener()));
        
    //QObject::connect(widget.treeTasks, SIGNAL(itemClicked(QTreeWidgetItem* ,int)), this, SLOT(checkTaskListener()));
    
    
    //Templates
    QObject::connect(widget.addTempBtn, SIGNAL(clicked()), this, SLOT(addTempListener()));
    
    
}

accueil::~accueil() {
    writeDom();
}


void accueil::addListListener() {    
    addListDialog *appAddList = new addListDialog(this);
    appAddList->setVisible(true);
}

void accueil::addTaskListener() {    
    if(widget.tableLists->currentRow()==-1) {
        QMessageBox::information(this,"Erreur","Aucune liste selectionnee !",0,0,0);
        return;
    }
    addTaskWindow *appAddTask = new addTaskWindow(this);
    appAddTask->setVisible(true);
}

void accueil::checkTaskListener() {
    cout << "Changement de check" <<endl;
    /*TODO*/
    
    
    
}

list<ListOfTask*> accueil::getTemplates() {
    return utilisateur.GetTemplates();
}


void accueil::enableBtnTask() {
    widget.removeTaskBtn->setDisabled(false);
    widget.modifyTaskBtn->setDisabled(false);
}

void accueil::disableBtnTask() {
    widget.removeTaskBtn->setDisabled(true);
    widget.modifyTaskBtn->setDisabled(true);
}


void accueil::addTempListener() {    
    addTempDialog *appAddTemp = new addTempDialog(this);
    appAddTemp->setVisible(true);
}


void accueil::addTemp(string name) {
    ListOfTask *newTemplate = new ListOfTask(name);
    utilisateur.addTemplate(newTemplate);
    
    int currentLigne = widget.tabletemps->rowCount();


    //On ajoute une ligne au tableau
    widget.tabletemps->setRowCount(currentLigne+1);

    //On créer les différents items que l'on va ajouter au tableau

    
    QTableWidgetItem* itemName = new QTableWidgetItem;
    itemName->setText(QString(name.c_str()));
    

    //On ajoute les données au tableau
    widget.tabletemps->setItem(currentLigne, 0, itemName);
    

    widget.tabletemps->resizeColumnsToContents();
    
    
}

void accueil::editListListener() {
    if(widget.tableLists->currentRow()==-1) {
        QMessageBox::information(this,"Erreur","Aucune liste selectionnee !",0,0,0);
        return;
    }
    editListDialog *appeditList = new editListDialog(this);
    appeditList->setVisible(true);
}


void accueil::editCurrentList(string newName) {
    
    int rowSelected = widget.tableLists->currentRow();
    
    ListOfTask* list = utilisateur.GetListByName(newName);
    
    widget.tableLists->item(rowSelected,0)->setText(QString(list->getName().c_str()));

    widget.tableLists->item(rowSelected,1)->setText(QString(list->getDate().toString().c_str()));

    widget.tableLists->resizeColumnsToContents();

}

void accueil::editTaskListener() {
    
    
    int rowSelected = widget.tableLists->currentRow();
    
    string nomList;
    if(rowSelected==-1) {
        QMessageBox::information(this,"Erreur","Aucune liste selectionnee !",0,0,0);
        return;
    }
    else { 
        QTableWidgetItem* itemNom = widget.tableLists->item(rowSelected,0);
        nomList = itemNom->text().toStdString(); 
    }
    
    
    ListOfTask *currentListOfTask = utilisateur.GetListByName(nomList);

    if(widget.treeTasks->currentItem()==NULL) {
        return;
    }
    
    string taskName = widget.treeTasks->currentItem()->text(0).toStdString();
    
    Task* editTask = recTaskFinder(currentListOfTask->getTasks(), taskName);

    if(editTask==NULL) {
        return;
    }
    
    editTaskWindow *appEditTask = new editTaskWindow(this, editTask);   
    appEditTask->setVisible(true);
    
    widget.removeTaskBtn->setDisabled(true);
    widget.modifyTaskBtn->setDisabled(true);
}


/**
 * 
 */
void accueil::supprTaskListener() {    

    int rowSelected = widget.tableLists->currentRow();
    
    string nomList;
    if(rowSelected==-1) {
        QMessageBox::information(this,"Erreur","Aucune liste selectionnee !",0,0,0);
        return;
    }
    else { 
        QTableWidgetItem* itemNom = widget.tableLists->item(rowSelected,0);
        nomList = itemNom->text().toStdString(); 
    }
    
    
    ListOfTask *currentListOfTask = utilisateur.GetListByName(nomList);

    if(widget.treeTasks->currentItem()==NULL) {
        return;
    }
    
    string taskName = widget.treeTasks->currentItem()->text(0).toStdString();
    
    Task* tmpTask = recTaskFinder(currentListOfTask->getTasks(), taskName);
   
    currentListOfTask->removeTask(tmpTask);
    
    list<Task*> underTask = currentListOfTask->getTasks();
    
    for (std::list<Task*>::iterator it = underTask.begin(); it != underTask.end(); ++it) {
        
        Task *t = *it;
        
        t->removeTask(tmpTask);
        
    }
    
    updateViewTasksList();
    
    widget.removeTaskBtn->setDisabled(true);
    widget.modifyTaskBtn->setDisabled(true);
    
}


//Ajout d'une liste
void accueil::addList(string name, Date date_, string selectTemplate) {
    
     
    ListOfTask *tmpListTasks = new ListOfTask(name,date_);
    
    if(!(selectTemplate=="")) {
    
        list<Task*> tasksTemplate = utilisateur.GetTemplateByName(selectTemplate)->getTasks();

        for (std::list<Task*>::iterator it = tasksTemplate.begin(); it != tasksTemplate.end(); ++it) {
            Task *tmpTask = *it;
       
            tmpListTasks->addTask(tmpTask);
        }
    
    }
    
    utilisateur.addList(tmpListTasks);
    
    
    int currentLigne = widget.tableLists->rowCount();


    //On ajoute une ligne au tableau
    widget.tableLists->setRowCount(currentLigne+1);

    //On créer les différents items que l'on va ajouter au tableau

    
    QTableWidgetItem* itemName = new QTableWidgetItem;
    itemName->setText(QString(name.c_str()));
    
    
    
    QTableWidgetItem* itemDate = new QTableWidgetItem;
    itemDate->setText(QString(tmpListTasks->getDate().getDate().c_str()));

    //On ajoute les données au tableau
    widget.tableLists->setItem(currentLigne, 0, itemName);
    
    widget.tableLists->setItem(currentLigne, 1, itemDate);


    widget.tableLists->resizeColumnsToContents();
    
    
}


/**
 * Ajout d'une tache
 * @param newTask
 * @param nbJour
 */
void accueil::addTopTask(Task *newTask) {
    
    //Task *newTask = new Task(name, "",false);
    
    
    //recuperation du no de la liste selectionne
    int rowSelected = widget.tableLists->currentRow();
    
    string nomList;
    if(rowSelected==-1) {
        QMessageBox::information(this,"Erreur","Aucune liste selectionnee !",0,0,0);
        return;
    }
    else { 
        QTableWidgetItem* itemNom = widget.tableLists->item(rowSelected,0);
        nomList = itemNom->text().toStdString();
              
    }
    
    
    ListOfTask *currentListOfTask = utilisateur.GetListByName(nomList);

    
    currentListOfTask->addTask(newTask);
    

    updateViewTasksList();

    widget.removeTaskBtn->setDisabled(true);
    widget.modifyTaskBtn->setDisabled(true);
    
}

/**
 * TODO Bloquer à une sous-tache
 * 
 * @param parentName
 * @param newTask
 * @param nbJour
 */
//Ajout d'une tache
void accueil::addChildTask(string parentName, Task *newTask) {
    
   // Task *newTask = new Task(ChildName, "",false);
    
    
    //recuperation du no de la liste selectionne
    int rowSelected = widget.tableLists->currentRow();
    
    string nomList;
    if(rowSelected==-1) {
        QMessageBox::information(this,"Erreur","Aucune liste selectionnee !",0,0,0);
        return;
    }
    else { 
        QTableWidgetItem* itemNom = widget.tableLists->item(rowSelected,0);
        nomList = itemNom->text().toStdString();
              
    }
    
    
    ListOfTask *currentListOfTask = utilisateur.GetListByName(nomList);

    
    list<Task*> top = currentListOfTask->getTasks();
    
   
    //On recupere la tache parente :
    Task* parentTask = recTaskFinder(top,parentName);
    
    if(parentTask==NULL) {
        cout <<"oups"<<endl;
    }
    else {
        parentTask->addTask(newTask);

       // cout << parentName << endl;
       // cout <<parentTask->toString()<<endl;
    }
    updateViewTasksList();
    
    widget.removeTaskBtn->setDisabled(true);
    widget.modifyTaskBtn->setDisabled(true);

}


Task* accueil::recTaskFinder(list<Task*> top, string name) {
    
    
    for (std::list<Task*>::iterator it = top.begin(); it != top.end(); ++it) {
        Task *tmpTask = *it;
        //cout << tmpTask->getTitre() << "/" << name << endl;
        if(tmpTask->getTitre()==name) {
            cout<<"Find : " << tmpTask->getTitre()<<endl;
            return tmpTask;
            
        }
        else {
           Task* retTask = recTaskFinder(tmpTask->getTasks(),name);
           if(retTask!=NULL) {
               return retTask;
           }
        }
        

        
    }
    
    return NULL;
    
   
}

// Supprime un element de la liste
void accueil::removeList() {
      //recuperation de la ligne selectionnée
    int rowSelected = widget.tableLists->currentRow();
    
    if(rowSelected==-1) {
        QMessageBox::information(this,"Erreur","Aucune liste selectionnee !",0,0,0);
    }
    else { 
    
        QTableWidgetItem* itemNom = widget.tableLists->item(rowSelected,0);

      

        string nomList(itemNom->text().toStdString());

        
        ListOfTask* list = utilisateur.GetListByName(nomList);

        utilisateur.removeList(list);

        widget.tableLists->removeRow(rowSelected);
        widget.tableLists->resizeColumnsToContents();
        
        widget.removeListBtn->setDisabled(true);
        widget.modifyListBtn->setDisabled(true);

    }
}

//Mets à jour la liste des taches en fonction de la liste selectionne
void accueil::updateViewTasksList() {
    
    widget.removeListBtn->setDisabled(false);
    widget.modifyListBtn->setDisabled(false);
    

    int nbTasks = widget.treeTasks->topLevelItemCount();
    for (int i=0; i<nbTasks;++i)
    {     
        QTreeWidgetItem *tmpItem = widget.treeTasks->takeTopLevelItem(0);
        delete tmpItem;
    }
    
    //recuperation du no de la liste selectionne
    
    int rowSelected = widget.tableLists->currentRow();
    
    string nomList;
    if(rowSelected==-1) {
        //QMessageBox::information(this,"Erreur","Aucune liste selectionnee !",0,0,0);
        return;
    }
    else { 
        QTableWidgetItem* itemNom = widget.tableLists->item(rowSelected,0);
        nomList = itemNom->text().toStdString();
              
    }
    
        
    ListOfTask *currentListOfTask = utilisateur.GetListByName(nomList);

   
    list<Task*> listOftasks = currentListOfTask->getTasks();
    
    
    for (std::list<Task*>::iterator it = listOftasks.begin(); it != listOftasks.end(); ++it) {
            Task *tmpTask = *it;
            string name = tmpTask->getTitre();
        
            QTreeWidgetItem *item = new QTreeWidgetItem;
            item->setText(0,QString(name.c_str()));
            item->setText(1,QString(tmpTask->getDeadLine().c_str()));
            
            if(tmpTask->isOrdo()) {
                ostringstream oss;
                oss << tmpTask->getNumber();
                string number = oss.str();

                item->setText(2,number.c_str());
            }
            
            if(!tmpTask->isCheck()) {
                item->setCheckState(3,Qt::Unchecked);
            } else {
                item->setCheckState(3,Qt::Checked);
            }

            widget.treeTasks->addTopLevelItem(item);
            
            list<Task*> listOfunderTasks = tmpTask->getTasks();
            
            
            recTaskView(item,listOfunderTasks);
            
        
    }
    
    
    widget.treeTasks->resizeColumnToContents(0);

}


void accueil::recTaskView(QTreeWidgetItem *item, list<Task*> listOfunderTasks) {
    
    for (std::list<Task*>::iterator its = listOfunderTasks.begin(); its != listOfunderTasks.end(); ++its) {

        Task *tmpTask2 = *its;

        string name = tmpTask2->getTitre();
        QTreeWidgetItem *item2 = new QTreeWidgetItem;
        
        if(tmpTask2->isOrdo()) {
            ostringstream oss;
            oss << tmpTask2->getNumber();
            string number = oss.str();

            item2->setText(2,number.c_str());
        }

        if(!tmpTask2->isCheck()) {
            item2->setCheckState(3,Qt::Unchecked);
        } else {
            item2->setCheckState(3,Qt::Checked);
        }
        
        item2->setText(0,QString(name.c_str()));
        item2->setText(1,QString(tmpTask2->getDeadLine().c_str()));
        item->addChild(item2);
        
        recTaskView(item2,tmpTask2->getTasks());

    }

    
}


ListOfTask* accueil::getSelectedList() {
    
    int rowSelected = widget.tableLists->currentRow();
    
    string nomList;
    if(rowSelected==-1) {
        QMessageBox::information(this,"Erreur","Aucune liste selectionnee !",0,0,0);
        return NULL;
    }
    else { 
        QTableWidgetItem* itemNom = widget.tableLists->item(rowSelected,0);
        nomList = itemNom->text().toStdString();
              
    }
    
        
    return utilisateur.GetListByName(nomList);
    
}



/**Gestion du fichier xml */

//Ecrit dans le fichier XML l'état de l'application
void accueil::writeDom() {
    
    clearDom();
    
    QDomDocument dom("sauvegarde");
    QFile doc_xml("save.xml");
    if(!doc_xml.open(QIODevice::ReadWrite))
    {
        QMessageBox::critical(this,"Erreur","Impossible d'ouvrir le ficher XML");
        doc_xml.close();
        return;
    }
    if(!dom.setContent(&doc_xml))
    {
        QMessageBox::critical(this,"Erreur","XML non valide");
        doc_xml.close();
        return;
    }
    doc_xml.close();
    
    //racine du document (listes)
    QDomElement docElem = dom.documentElement();
    
    //parcours des listes de l'utilisateur
    std::list<ListOfTask*> listListTask = utilisateur.GetListOfTasksLists();
    std::list<ListOfTask*>::iterator it = listListTask.begin();
    std::list<ListOfTask*>::const_iterator itEnd = listListTask.end();
    for(;it!=itEnd;++it) {
        ListOfTask* gr = *it;
        QDomElement liste = dom.createElement("liste"); // On créé un QDomElement qui a comme nom de balise "liste".
        liste.setAttribute("nom", QString(gr->getName().c_str())); 
        liste.setAttribute("date", QString(gr->getDate().getDate().c_str())); 
        docElem.appendChild(liste);// On ajoute liste dans la balise listes
        
        //parcours des taches de la liste
        std::list<Task*> listTask = gr->getTasks();
        std::list<Task*>::iterator it = listTask.begin();
        std::list<Task*>::const_iterator itEnd = listTask.end();
        for(;it!=itEnd;++it){
            Task* t = *it;
            QDomElement tache = dom.createElement("tache"); // On créé un QDomElement qui a comme nom de balise "tache".
            tache.setAttribute("nom", QString(t->getTitre().c_str()));
            
            if(t->isOrdo()) {
                tache.setAttribute("ordo", "1");
                tache.setAttribute("number", t->getNumber());
            }
            else {
                tache.setAttribute("ordo", "0");
                tache.setAttribute("number", -1);
            }
            
            
            if(t->isEcheance()) {
                tache.setAttribute("echeance",1);
                tache.setAttribute("deadline", QString(t->getDeadLine().c_str()));
            }
            else {
                tache.setAttribute("echeance",0);
                tache.setAttribute("deadline", "");
            }
            
            if(t->isCheck()) {
                tache.setAttribute("check",1);
            }
            else {
                tache.setAttribute("check",0);
            }
            
            
            

            liste.appendChild(recTaskDom(dom, tache, t->getTasks()));

        }
    }   
    //Ecriture dans le fichier XML
    QString write = dom.toString();
    if(!doc_xml.open(QIODevice::WriteOnly))
    {
        doc_xml.close();
        QMessageBox::critical(this,"Erreur","Impossible d'écrire dans le document XML");
        return;
    }
    QTextStream stream(&doc_xml);
    stream << write; 
}



QDomElement accueil::recTaskDom(QDomDocument dom, QDomElement item, list<Task*> listOfunderTasks) {
    
    for (std::list<Task*>::iterator its = listOfunderTasks.begin(); its != listOfunderTasks.end(); ++its) {

        Task *t = *its;

        QDomElement tache2 = dom.createElement("tache"); // On créé un QDomElement qui a comme nom de balise "tache".
        tache2.setAttribute("nom", QString(t->getTitre().c_str()));


        if(t->isOrdo()) {
            tache2.setAttribute("ordo", "1");
            tache2.setAttribute("number", t->getNumber());
        }
        else {
            tache2.setAttribute("ordo", "0");
            tache2.setAttribute("number", -1);
        }


        if(t->isEcheance()) {
            tache2.setAttribute("echeance",1);
            tache2.setAttribute("deadline", QString(t->getDeadLine().c_str()));
        }
        else {
            tache2.setAttribute("echeance",0);
            tache2.setAttribute("deadline", "");
        }
        
        if(t->isCheck()) {
            tache2.setAttribute("check",1);
        }
        else {
            tache2.setAttribute("check",0);
        }
        
         
        item.appendChild(recTaskDom(dom, tache2, t->getTasks()));

        
        
        
    }
    return item;
}


//remise en etat du logiciel

void accueil::restoreDom() {

     QDomDocument dom;
     QFile file("save.xml");
     file.open(QIODevice::ReadOnly);
     dom.setContent(&file);
     file.close();
     
     QDomElement docElem = dom.documentElement();
     QDomNode listeCourante = docElem.firstChild();
     while(!listeCourante.isNull()) 
     {
        QDomElement e = listeCourante.toElement(); 
        QString nom = e.attribute("nom");
        QString date= e.attribute("date");

        //Récupération du jour, du mois et de l'année pour contruire la liste
        string ladate(date.toStdString());
        vector<string> VecStr;
        split(VecStr, ladate, '/');
        string jour = VecStr[0];
        string mois = VecStr[1];
        string annee = VecStr[2];

        ListOfTask *list = new ListOfTask(nom.toStdString(),Date(atoi(jour.c_str()),atoi(mois.c_str()),atoi(annee.c_str())));
        utilisateur.addList(list);

        QDomNode tacheCourante = listeCourante.firstChild();
        while(!tacheCourante.isNull()) {
            QDomElement t = tacheCourante.toElement();
            
            QString nomTache = t.attribute("nom");
            bool ordo = (t.attribute("ordo")=="1");

            QString numero = t.attribute("number");
            bool echeance = (t.attribute("echeance")=="1");
            
            QString deadline = t.attribute("deadline");
            
            Task *task = new Task(nomTache.toStdString(),ordo );
            
            if(ordo) {
                task->setNumber(atoi(numero.toStdString().c_str()));
            }
            
            if(t.attribute("check")=="1") {
                task->setCheck(true);
            }
            else {
                task->setCheck(false);
            }
            
            task->setEcheance(echeance);
            
            task->setDeadLine(deadline.toStdString());
            
            
            list->addTask(task);
            
            QDomNode sousTacheCourante = tacheCourante.firstChild();
            while(!sousTacheCourante.isNull()) {
                QDomElement s = sousTacheCourante.toElement();

                QString nomTacheS = s.attribute("nom");
                bool ordoS = (s.attribute("ordo")=="1");

                QString numeroS = s.attribute("number");
                bool echeanceS = (s.attribute("echeance")=="1");

                QString deadlineS = s.attribute("deadline");

                Task *ssTask = new Task(nomTacheS.toStdString(),ordoS );
                
                if(ordoS) {
                    ssTask->setNumber(atoi(numeroS.toStdString().c_str()));
                }

                ssTask->setEcheance(echeanceS);

                ssTask->setDeadLine(deadlineS.toStdString());
                
                task->addTask(ssTask);
                
                sousTacheCourante = sousTacheCourante.nextSibling();
                }
            
            tacheCourante = tacheCourante.nextSibling();
        }

        int currentLigne = widget.tableLists->rowCount();

        //On ajoute une ligne au tableau
        widget.tableLists->setRowCount(currentLigne+1);
        
        QTableWidgetItem* itemName = new QTableWidgetItem;
        itemName->setText(nom);

        QTableWidgetItem* itemDate = new QTableWidgetItem;
        itemDate->setText(date);

        //On ajoute les données au tableau
        widget.tableLists->setItem(currentLigne, 0, itemName);
        widget.tableLists->setItem(currentLigne, 1, itemDate);

        //widget.listeListeTachesAFaire->resizeColumnsToContents();

        listeCourante = listeCourante.nextSibling();
     }
}

void accueil::split(vector<string>& vecteur, string chaine, char separateur)
{
        vecteur.clear();

        string::size_type stTemp = chaine.find(separateur);
        
        while(stTemp != string::npos)
        {
                vecteur.push_back(chaine.substr(0, stTemp));
                chaine = chaine.substr(stTemp + 1);
                stTemp = chaine.find(separateur);
        }
        
        vecteur.push_back(chaine);
}




//Vide le fichier XML
void accueil::clearDom() {
    QDomDocument dom;
    
    QFile doc_xml("save.xml");
    if(!doc_xml.open(QIODevice::ReadWrite))
    {
        QMessageBox::critical(this,"Erreur","Impossible d'ouvrir le ficher XML");
        doc_xml.close();
        return;
    }
    if(!dom.setContent(&doc_xml))
    {
        QMessageBox::critical(this,"Erreur","Impossible d'ouvrir le ficher XML");
        doc_xml.close();
        return;
    }
      
    QDomElement docElem = dom.documentElement();
              
    QDomNode n = docElem.firstChild();
    while(!n.isNull()) {
        QDomNode copy = n.nextSibling();
        QDomElement e = n.toElement();

        if(!e.isNull()) {
                docElem.removeChild(n);
        }
        n = copy;
    }
    QString write_doc = dom.toString();

    QTextStream stream(&doc_xml);
    doc_xml.close();
    
    doc_xml.open(QIODevice::WriteOnly|QFile::Truncate);
    stream << write_doc;
    doc_xml.close();
}










